/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package phidgetmotion.evaluation;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

/**
 *
 * @author monika
 */
public class User implements Serializable {

	private static final long serialVersionUID = -8664225542455700360L;
	private String username;
	private int age;
	private boolean isMale;
	private ArrayList<Experiment> test;

	public User() {
		this("", -1, true, new ArrayList<Experiment>());
	}

	public User(String name, int age, boolean isMale, ArrayList<Experiment> test) {
		super();
		this.username = name;
		this.age = age;
		this.isMale = isMale;
		this.test = test;
	}

	public void setUsername(String name) {
		this.username = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void setIsMale(boolean isMale) {
		this.isMale = isMale;
	}

	public void setTest(ArrayList<Experiment> test) {
		this.test = test;
	}

	public String getUsername() {
		return this.username;
	}

	public int getAge() {
		return this.age;
	}

	public boolean getIsMale() {
		return this.isMale;
	}

	public ArrayList<Experiment> getTest() {
		return this.test;
	}

	public void addExperiment(Experiment e) {
		this.test.add(e);
	}

	public long getRecognitionTime() {
		long time = 0;
		int count = 0;
		for (int i = 0; i < test.size(); i++) {
			if (test.get(i).getRecognitionTime() > 0) {
				time += test.get(i).getRecognitionTime();
				count++;
			}
		}
		if (count > 0) {
			time = time / count;
			return time;
		}
		else return -1;
	}
	
	public double getStdDev(){
		long mid = getRecognitionTime();
		if(mid==-1) return -1;
		long variance = 0;
		int count = 0;
		for (int i = 0; i < test.size(); i++) {
			if (test.get(i).getRecognitionTime() > 0) {
				long dist = test.get(i).getRecognitionTime() - mid;
				variance += dist*dist;
				count++;
			}
		}
		if (count > 0) {
			variance = variance / count;
		}
		return Math.sqrt(variance);
	}
	
	@SuppressWarnings("unchecked")
	public long getQuartil(int quartil){
		double q = quartil / 4.0;
		if (quartil > 4)
			quartil = 4;
		ArrayList<Experiment> copyList = (ArrayList<Experiment>) test.clone();
		Collections.sort(copyList);
		int size = copyList.size();
		if (size > 0) {
			int index = (int)(size * q);
			if (((int)(size * q)) % 2 == 0)
				return (copyList.get(index).getRecognitionTime() + copyList.get(index+1).getRecognitionTime())/2;
			else
				return copyList.get(index).getRecognitionTime();
		}
		return 0L;
	}
	
	public long getMinTime() {
		long min = Long.MAX_VALUE;
		for (int i = 0; i < test.size(); i++) {
			long recogTime = test.get(i).getRecognitionTime();
			if (recogTime < min && recogTime>=0) min = recogTime;
		}
		return min;
	}
	
	public long getMaxTime() {
		long max = 0;
		for (int i = 0; i < test.size(); i++) {
			if (test.get(i).getRecognitionTime() > max) max = test.get(i).getRecognitionTime();
		}
		return max;
	}

	public long getRecognitionTime(int classId) {
		long time = 0;
		int count = 0;
		for (int i = 0; i < test.size(); i++) {
			if (test.get(i).getActivity() == classId) {
				if (test.get(i).getRecognitionTime() > 0) {
					time += test.get(i).getRecognitionTime();
				}
				count++;
			}
		}
		if (count > 0) {
			time = time / count;
			return time;
		}
		else return -1;
	}

	public double getErrorRate() {
		return 1-getRecognitionRate();
	}

	public double getRecognitionRate() {
		double rate = 0.0;
		int recognizedActivities = 0;
		for (int i = 0; i < test.size(); i++) {
			Experiment exp = test.get(i);
			if (exp.getRecognitionTime() >= 0L)
				recognizedActivities++;
		}
		if (test.size() > 0) {
			rate = (double)recognizedActivities / test.size();
		}
		return rate;
	}

	public void saveTable(String prefix, String[] classNames) throws IOException {
		BufferedWriter allOutput = new BufferedWriter(new FileWriter(prefix+"_" + username + ".csv"));
		allOutput.write("Number");
		ArrayList<ArrayList<Experiment>> lists = new ArrayList<ArrayList<Experiment>>();
		for(int i=0; i<classNames.length; i++){
			lists.add(new ArrayList<Experiment>());
			allOutput.write(";"+classNames[i]+" (ms) ");
		}
		allOutput.write('\n');
		int maxListLength = 0;
		Iterator<Experiment> iter = test.iterator();
		while(iter.hasNext()){
			Experiment exp = iter.next();
			ArrayList<Experiment> list = lists.get(exp.getActivity());
			list.add(exp);
			if(list.size()>maxListLength) maxListLength = list.size();
		}
		for(int i=0; i<maxListLength; i++)
		{
			allOutput.write(String.valueOf(i+1));
			for(int j=0; j<classNames.length; j++){
				ArrayList<Experiment> list = lists.get(j);
				Experiment exp = list.get(i);
				allOutput.write(";");
				if(exp!=null) allOutput.write(String.valueOf(exp.getRecognitionTime())); 
			}
			allOutput.write("\n");
		}	
		allOutput.close();
		
	}
}
